package com.module.ad_gromore.ad;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;

import com.module.ad_gromore.LogADUtils;
import com.module.ad_gromore.VideoAdListener;
import com.module.ad_gromore.manager.AdRewardManager;
import com.bytedance.msdk.adapter.util.Logger;
import com.bytedance.msdk.api.AdError;
import com.bytedance.msdk.api.TToast;
import com.bytedance.msdk.api.reward.RewardItem;
import com.bytedance.msdk.api.v2.GMAdConstant;
import com.bytedance.msdk.api.v2.ad.reward.GMRewardedAdListener;
import com.bytedance.msdk.api.v2.ad.reward.GMRewardedAdLoadCallback;

import java.util.Map;

/**
 * 激励视频
 */
public class VideoAd {
    private AdRewardManager mAdRewardManager;
    private boolean mLoadSuccess = false;
    private final String TAG = "广告";
    private VideoAdListener AdFullVideoManager;
    private String adUnitId;

    private static VideoAd videoAd;

    public static void loadAd(Activity context, final String adUnitId, VideoAdListener AdFullVideoManager) {
        videoAd = new VideoAd(adUnitId, AdFullVideoManager);
        videoAd.load(context, GMAdConstant.VERTICAL);
        if (context instanceof FragmentActivity) {
            ((FragmentActivity) context).getLifecycle().addObserver(new DefaultLifecycleObserver() {
                @Override
                public void onDestroy(@NonNull LifecycleOwner owner) {
                    DefaultLifecycleObserver.super.onDestroy(owner);
                    if (videoAd != null) {
                        videoAd.onDestroy();
                        videoAd = null;
                    }
                    ((FragmentActivity) context).getLifecycle().removeObserver(this);
                }
            });
        }
    }

    private VideoAd(String adUnitId, VideoAdListener AdFullVideoManager) {
        this.adUnitId = adUnitId;
        this.AdFullVideoManager = AdFullVideoManager;
    }

    private void load(Activity context, final int orientation) {
        mAdRewardManager = new AdRewardManager(context, new GMRewardedAdLoadCallback() {
            @Override
            public void onRewardVideoLoadFail(AdError adError) {
                mLoadSuccess = false;
                LogADUtils.e(TAG, "load RewardVideo ad error : " + adError.code + ", " + adError.message);
                mAdRewardManager.printLoadFailAdnInfo();
            }

            @Override
            public void onRewardVideoAdLoad() {
                mLoadSuccess = true;
                LogADUtils.e(TAG, "load RewardVideo ad success !");
                // 获取本次waterfall加载中，加载失败的adn错误信息。
                mAdRewardManager.printLoadAdInfo(); //打印已经加载广告的信息
                mAdRewardManager.printLoadFailAdnInfo();//打印加载失败的adn错误信息
            }

            @Override
            public void onRewardVideoCached() {
                mLoadSuccess = true;
                LogADUtils.d(TAG, "onRewardVideoCached....缓存成功");
                TToast.show(context, "激励视频素材缓存成功！");
                showRewardAd(context);//加载并展示

            }
        });
        mAdRewardManager.loadAdWithCallback(adUnitId, orientation);

    }

    /**
     * 展示广告
     */
    private void showRewardAd(Activity activity) {
        if (mLoadSuccess && mAdRewardManager != null) {
            if (mAdRewardManager.getGMRewardAd() != null && mAdRewardManager.getGMRewardAd().isReady()) {
                //在获取到广告后展示,强烈建议在onRewardVideoCached回调后，展示广告，提升播放体验
                //该方法直接展示广告，如果展示失败了（如过期），会回调onVideoError()
                //展示广告，并传入广告展示的场景
                mAdRewardManager.getGMRewardAd().setRewardAdListener(mGMRewardedAdListener);
                mAdRewardManager.getGMRewardAd().setRewardPlayAgainListener(mGMRewardedPlayAgainListener);
                mAdRewardManager.getGMRewardAd().showRewardAd(activity);
                mAdRewardManager.printSHowAdInfo();//打印已经展示的广告信息
                mLoadSuccess = false;
            } else {
                LogADUtils.d(TAG, "当前广告不满足show的条件");
            }
        } else {
            LogADUtils.d(TAG, "请先加载广告");
        }
    }

    private GMRewardedAdListener mGMRewardedAdListener = new GMRewardedAdListener() {

        /**
         * 广告的展示回调 每个广告仅回调一次
         */
        public void onRewardedAdShow() {
            LogADUtils.d(TAG, "onRewardedAdShow");
            if (AdFullVideoManager != null) {
                AdFullVideoManager.onStart();
            }
        }

        /**
         * show失败回调。如果show时发现无可用广告（比如广告过期或者isReady=false），会触发该回调。
         * 开发者应该结合自己的广告加载、展示流程，在该回调里进行重新加载。
         * @param adError showFail的具体原因
         */
        @Override
        public void onRewardedAdShowFail(AdError adError) {
            if (adError == null) {
                return;
            }
            LogADUtils.d(TAG, "onRewardedAdShowFail, errCode: " + adError.code + ", errMsg: " + adError.message);
            // 开发者应该结合自己的广告加载、展示流程，在该回调里进行重新加载
        }

        /**
         * 注意Admob的激励视频不会回调该方法
         */
        @Override
        public void onRewardClick() {
            LogADUtils.d(TAG, "onRewardClick");

        }

        /**
         * 广告关闭的回调
         */
        public void onRewardedAdClosed() {
            LogADUtils.d(TAG, "onRewardedAdClosed");
        }

        /**
         * 视频播放完毕的回调 Admob广告不存在该回调
         */
        public void onVideoComplete() {
            LogADUtils.d(TAG, "onVideoComplete");
        }

        /**
         * 1、视频播放失败的回调
         */
        public void onVideoError() {
            LogADUtils.d(TAG, "onVideoError");
        }

        /**
         * 激励视频播放完毕，验证是否有效发放奖励的回调
         */
        public void onRewardVerify(RewardItem rewardItem) {
            Map<String, Object> customData = rewardItem.getCustomData();
            if (customData != null) {
                // 首先判断是否启用了GroMore的服务端验证
                Boolean isGroMoreServerSideVerify = (Boolean) customData.get(RewardItem.KEY_IS_GROMORE_SERVER_SIDE_VERIFY);
                if (isGroMoreServerSideVerify != null && isGroMoreServerSideVerify) {
                    // 开启了GroMore的服务端激励验证，这里可以获取GroMore的服务端激励验证信息
                    boolean isVerify = rewardItem.rewardVerify();
                    // 如果isVerify=false，则可以根据下面的错误码来判断为什么是false，
                    //  1、如果errorCode为40001/40002/50001/50002，则是因为请求异常导致，媒体可以根据自己的判断决定是否发放奖励。
                    //  2、否则，就是媒体服务端回传的验证结果是false，此时应该不发放奖励。

                    Integer reason = (Integer) customData.get(RewardItem.KEY_REASON);
                    if (reason != null) {
                        Logger.d(TAG, "rewardItem，开发者服务器回传的reason，开发者不传时为空");
                    }
                    Integer errorCode = (Integer) customData.get(RewardItem.KEY_ERROR_CODE);
                    if (errorCode != null) {
                        String errorMsg = (String) customData.get(RewardItem.KEY_ERROR_MSG);
                        Logger.d(TAG, "rewardItem, gromore服务端验证异常时的错误信息，未发生异常时为0或20000：errorCode:" + errorCode + ", errMsg: " + errorMsg);
                    }
                    String gromoreExtra = (String) customData.get(RewardItem.KEY_GROMORE_EXTRA);
                    Logger.d(TAG, "rewardItem, 开发者通过AdSlot传入的extra信息，会透传给媒体的服务器。开发者不传时为空，extra:" + gromoreExtra);
                    String transId = (String) customData.get(RewardItem.KEY_TRANS_ID);
                    Logger.d(TAG, "rewardItem, gromore服务端验证产生的transId，一次广告播放会产生的唯一的transid: " + transId);
                } else {
                    // 未开启GroMore的服务端激励验证，这里获取adn的激励验证信息
                    String adnName = (String) customData.get(RewardItem.KEY_ADN_NAME);
                    if (!TextUtils.isEmpty(adnName)) {
                        switch (adnName) {
                            case RewardItem.KEY_GDT:
                                Logger.d(TAG, "rewardItem gdt: " + customData.get(RewardItem.KEY_GDT_TRANS_ID));
                                break;
                        }
                    }
                }
            }
            LogADUtils.d(TAG, "onRewardVerify");
            if (AdFullVideoManager != null) {
                AdFullVideoManager.onComplete();
            }
        }

        /**
         * - Mintegral GDT Admob广告不存在该回调
         */
        @Override
        public void onSkippedVideo() {

        }

    };

    //穿山甲再看一次监听
    private GMRewardedAdListener mGMRewardedPlayAgainListener = new GMRewardedAdListener() {
        /**
         * 广告的展示回调 每个广告仅回调一次
         */
        public void onRewardedAdShow() {
            LogADUtils.d(TAG, "onRewardedAdShow---play again");

        }

        /**
         * show失败回调。如果show时发现无可用广告（比如广告过期或者isReady=false），会触发该回调。
         * 开发者应该结合自己的广告加载、展示流程，在该回调里进行重新加载。
         * @param adError showFail的具体原因
         */
        @Override
        public void onRewardedAdShowFail(AdError adError) {
            if (adError == null) {
                return;
            }
            LogADUtils.d(TAG, "onRewardedAdShowFail---play again, errCode: " + adError.code + ", errMsg: " + adError.message);
            // 开发者应该结合自己的广告加载、展示流程，在该回调里进行重新加载
        }

        /**
         * 注意Admob的激励视频不会回调该方法
         */
        @Override
        public void onRewardClick() {
            LogADUtils.d(TAG, "onRewardClick---play again");

        }

        /**
         * 广告关闭的回调
         */
        public void onRewardedAdClosed() {
            LogADUtils.d(TAG, "onRewardedAdClosed---play again");

        }

        /**
         * 视频播放完毕的回调 Admob广告不存在该回调
         */
        public void onVideoComplete() {
            LogADUtils.d(TAG, "onVideoComplete---play again");

        }

        /**
         * 1、视频播放失败的回调
         */
        public void onVideoError() {
            LogADUtils.d(TAG, "onVideoError---play again");

        }

        /**
         * 激励视频播放完毕，验证是否有效发放奖励的回调
         */
        public void onRewardVerify(RewardItem rewardItem) {
            Map<String, Object> customData = rewardItem.getCustomData();
            if (customData != null) {
                // 首先判断是否启用了GroMore的服务端验证
                Boolean isGroMoreServerSideVerify = (Boolean) customData.get(RewardItem.KEY_IS_GROMORE_SERVER_SIDE_VERIFY);
                if (isGroMoreServerSideVerify != null && isGroMoreServerSideVerify) {
                    // 开启了GroMore的服务端激励验证，这里可以获取GroMore的服务端激励验证信息
                    boolean isVerify = rewardItem.rewardVerify();
                    // 如果isVerify=false，则可以根据下面的错误码来判断为什么是false，
                    //  1、如果errorCode为40001/40002/50001/50002，则是因为请求异常导致，媒体可以根据自己的判断决定是否发放奖励。
                    //  2、否则，就是媒体服务端回传的验证结果是false，此时应该不发放奖励。

                    Integer reason = (Integer) customData.get(RewardItem.KEY_REASON);
                    if (reason != null) {
                        Logger.d(TAG, "rewardItem，开发者服务器回传的reason，开发者不传时为空");
                    }
                    Integer errorCode = (Integer) customData.get(RewardItem.KEY_ERROR_CODE);
                    if (errorCode != null) {
                        String errorMsg = (String) customData.get(RewardItem.KEY_ERROR_MSG);
                        Logger.d(TAG, "rewardItem, gromore服务端验证异常时的错误信息，未发生异常时为0或20000：errorCode:" + errorCode + ", errMsg: " + errorMsg);
                    }
                    String gromoreExtra = (String) customData.get(RewardItem.KEY_GROMORE_EXTRA);
                    Logger.d(TAG, "rewardItem, 开发者通过AdSlot传入的extra信息，会透传给媒体的服务器。开发者不传时为空，extra:" + gromoreExtra);
                    String transId = (String) customData.get(RewardItem.KEY_TRANS_ID);
                    Logger.d(TAG, "rewardItem, gromore服务端验证产生的transId，一次广告播放会产生的唯一的transid: " + transId);
                } else {
                    // 未开启GroMore的服务端激励验证，这里获取adn的激励验证信息
                    String adnName = (String) customData.get(RewardItem.KEY_ADN_NAME);
                    if (!TextUtils.isEmpty(adnName)) {
                        switch (adnName) {
                            case RewardItem.KEY_GDT:
                                Logger.d(TAG, "rewardItem gdt: " + customData.get(RewardItem.KEY_GDT_TRANS_ID));
                                break;
                        }
                    }
                    //穿山甲服务端验证新增的接口参数也放在customData中，可以按需获取数据，如：
                    if (customData != null) {
                        String rewardType = (String) customData.get(RewardItem.KEY_REWARD_TYPE); //获取奖励类型
                        Bundle extraInfo = (Bundle) customData.get(RewardItem.KEY_EXTRA_INFO); //获取额外参数
                        //从extraInfo中拿参数
//                            float rewardPropose = extraInfo.getFloat(TTRewardVideoAd.REWARD_EXTRA_KEY_REWARD_PROPOSE); //获取奖励百分比
                    }
                }
            }
            LogADUtils.d(TAG, "onRewardVerify---play again");
        }

        /**
         * - Mintegral GDT Admob广告不存在该回调
         */
        @Override
        public void onSkippedVideo() {

        }
    };

    public void onDestroy() {
        if (mAdRewardManager != null) {
            mAdRewardManager.destroy();
        }
    }
}
